#include <stdio.h>
#include "kfifo.h"
#include "main.h"	
#include "msg.h"
#include "key.h"
#include "tim.h"
#include "sw_timer.h"
#include "led.h"
#include "config.h"


//LED RED	PA11    TIM1_CH4
//LED BLUE	PA8     TIM1_CH1

uint8_t led_red_mode = 0;
uint8_t led_red_tiemr = 0xff;
uint8_t led_red_pwm = 0;
uint8_t led_red_direction = 0;
uint8_t led_red_level = 0;

uint8_t led_blue_mode = 0;
uint8_t led_blue_tiemr = 0xff;
uint8_t led_blue_pwm = 0;
uint8_t led_blue_direction = 0;
uint8_t led_blue_level = 0;





void app_led_gpio_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);

    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);

    /*Configure GPIO pins : PA8 PA11 */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void app_led_on(uint8_t led)
{
#ifdef SUPPORT_PWM_LED
    if(led & LED_RED)
		HAL_TIM1_pwm4_set(SUPPORT_PWM_LED_BRIGHT);
	if(led & LED_BLUE)
		HAL_TIM1_pwm1_set(SUPPORT_PWM_LED_BRIGHT);
#else
	if(led & LED_RED)
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);
	if(led & LED_BLUE)
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
#endif
}

void app_led_off(uint8_t led)
{
#ifdef SUPPORT_PWM_LED
    if(led & LED_RED)
        HAL_TIM1_pwm4_set(100);
    if(led & LED_BLUE)
        HAL_TIM1_pwm1_set(100);
#else
	if(led & LED_RED)
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
	if(led & LED_BLUE)
		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
#endif
}

void app_led_red_callback(void)
{
    //BOX_LOG("red_callback: %d\n", led_mode);
    switch(led_red_mode)
	{
#ifdef SUPPORT_PWM_LED
		case LED_MODE_RED_BREATHE_LIGHT:
			if(led_red_direction)
            {
                led_red_pwm++;
                if(led_red_pwm == 100)
                    led_red_direction = 0;
            }
            else
            {
                led_red_pwm--;
                if(led_red_pwm == 0)
                    led_red_direction = 1;
            }

            //BOX_LOG("pwm4: %d\n", led_blue_pwm);
            HAL_TIM1_pwm4_set(100 - led_red_pwm);
			break;
#endif
        case LED_MODE_RED_ON_1S:
            app_led_red_timer_stop();
			app_led_off(LED_RED);
			break;
        case LED_MODE_RED_ON_3S:
			app_led_red_timer_stop();
			app_led_off(LED_RED);
			break;
        case LED_MODE_RED_ON_5S:
			app_led_red_timer_stop();
			app_led_off(LED_RED);
			break;
        case LED_MODE_RED_FLASH:
			if(led_red_level)
			{
				app_led_off(LED_RED);
				led_red_level = 0;
			}
			else
			{
				app_led_on(LED_RED);
				led_red_level = 1;
			}
			break;
	}
}

void app_led_red_timer_stop(void)
{
    if(led_red_tiemr != 0xff)
        led_red_tiemr = sw_timer_stop(led_red_tiemr);
}

void app_led_blue_callback(void)
{
    switch(led_blue_mode)
	{
#ifdef SUPPORT_PWM_LED
		case LED_MODE_BLUE_BREATHE_LIGHT:
			if(led_blue_direction)
            {
                led_blue_pwm++;
                if(led_blue_pwm == 100)
                    led_blue_direction = 0;
            }
            else
            {
                led_blue_pwm--;
                if(led_blue_pwm == 0)
                    led_blue_direction = 1;
            }

            //BOX_LOG("pwm1: %d\n", led_blue_pwm);
            HAL_TIM1_pwm1_set(100 - led_blue_pwm);
			break;
#endif
        case LED_MODE_BLUE_ON_1S:
            app_led_blue_timer_stop();
			app_led_off(LED_BLUE);
			break;
        case LED_MODE_BLUE_ON_3S:
			app_led_blue_timer_stop();
			app_led_off(LED_BLUE);
			break;
        case LED_MODE_BLUE_ON_5S:
			app_led_blue_timer_stop();
			app_led_off(LED_BLUE);
			break;
        case LED_MODE_BLUE_FLASH:
			if(led_blue_level)
			{
				app_led_off(LED_BLUE);
				led_blue_level = 0;
			}
			else
			{
				app_led_on(LED_BLUE);
				led_blue_level = 1;
			}
			break;
	}
}

void app_led_blue_timer_stop(void)
{
    if(led_blue_tiemr != 0xff)
        led_blue_tiemr = sw_timer_stop(led_blue_tiemr);
}


void app_led_set_mode_red(uint8_t mode)
{
    led_red_mode = mode;
    app_led_red_timer_stop();
    switch(mode)
	{
#ifdef SUPPORT_PWM_LED
        case LED_MODE_RED_BREATHE_LIGHT:
            HAL_TIM1_pwm4_set(100);
            HAL_TIM1_pwm4_start();
            led_red_pwm = 0;
            led_red_direction = 1;
            led_red_tiemr = sw_timer_start(30, 1, app_led_red_callback);
            break;
#endif
        case LED_MODE_RED_ON:
            app_led_on(LED_RED);
            break;
        case LED_MODE_RED_OFF:
            app_led_off(LED_RED);
            break;
        case LED_MODE_RED_ON_1S:
			app_led_on(LED_RED);
			led_red_level = 1;
			led_red_tiemr = sw_timer_start(1000, 1, app_led_red_callback);
		    break;
        case LED_MODE_RED_ON_3S:
			app_led_on(LED_RED);
			led_red_level = 1;
			led_red_tiemr = sw_timer_start(3000, 1, app_led_red_callback);
		    break;
        case LED_MODE_RED_ON_5S:
			app_led_on(LED_RED);
			led_red_level = 1;
			led_red_tiemr = sw_timer_start(5000, 1, app_led_red_callback);
		    break;
    	case LED_MODE_RED_FLASH:
    		app_led_on(LED_RED);
    		led_red_level = 1;
    		led_red_tiemr = sw_timer_start(500, 1, app_led_red_callback);
    		break;
    }
}

void app_led_set_mode_blue(uint8_t mode)
{
    led_blue_mode = mode;
    app_led_blue_timer_stop();
    switch(mode)
	{
#ifdef SUPPORT_PWM_LED
        case LED_MODE_BLUE_BREATHE_LIGHT:
            HAL_TIM1_pwm1_set(100);
            HAL_TIM1_pwm1_start();
            led_blue_pwm = 0;
            led_blue_direction = 1;
            led_blue_tiemr = sw_timer_start(30, 1, app_led_blue_callback);
            break;
#endif
        case LED_MODE_BLUE_ON:
            app_led_on(LED_BLUE);
            break;
        case LED_MODE_BLUE_OFF:
            app_led_off(LED_BLUE);
            break;
        case LED_MODE_BLUE_ON_1S:
			app_led_on(LED_BLUE);
			led_blue_level = 1;
			led_blue_tiemr = sw_timer_start(1000, 1, app_led_blue_callback);
		    break;
        case LED_MODE_BLUE_ON_3S:
			app_led_on(LED_BLUE);
			led_blue_level = 1;
			led_blue_tiemr = sw_timer_start(3000, 1, app_led_blue_callback);
		    break;
        case LED_MODE_BLUE_ON_5S:
			app_led_on(LED_BLUE);
			led_blue_level = 1;
			led_blue_tiemr = sw_timer_start(5000, 1, app_led_blue_callback);
		    break;
        case LED_MODE_BLUE_FLASH:
			app_led_on(LED_BLUE);
			led_blue_level = 1;
			led_blue_tiemr = sw_timer_start(500, 1, app_led_blue_callback);
		    break;
	}
}

void app_led_set_mode(uint8_t mode)
{
    BOX_LOG("led set mode: %d\n", mode);
    if(mode >= LED_MODE_BLUE_BREATHE_LIGHT)
    {
        app_led_set_mode_blue(mode);
    }
    else if(mode >= LED_MODE_RED_BREATHE_LIGHT)
    {
        app_led_set_mode_red(mode);
    }
    else
    {
        led_red_mode = mode;
        led_blue_mode = mode;
        app_led_red_timer_stop();
        app_led_blue_timer_stop();
    	switch(mode)
    	{
    		case LED_MODE_ALL_OFF:
    			app_led_off(LED_RED | LED_BLUE);
    		break;
    		
    		case LED_MODE_ALL_ON:
    			app_led_on(LED_RED | LED_BLUE);
    		break;
        }
    }
}

void app_led_init(void)
{
    BOX_LOG("app_led_init\n");

#ifdef SUPPORT_PWM_LED
    MX_TIM1_Init();
    HAL_TIM1_pwm4_set(100);
    HAL_TIM1_pwm4_start();
    HAL_TIM1_pwm1_set(100);
    HAL_TIM1_pwm1_start();
#else
    app_led_gpio_init();
#endif
	//app_led_off(LED_RED | LED_BLUE);
	
	//app_led_set_mode(LED_MODE_BLUE_ON_3S);
	//app_led_set_mode(LED_MODE_RED_FLASH);

    //app_led_set_mode(LED_MODE_RED_BREATHE_LIGHT);
    //app_led_set_mode(LED_MODE_BLUE_BREATHE_LIGHT);
}



